//
//  OtherObservableViewController.swift
//  Example
//
//  Created by T AO on 2022/2/12.
//

import UIKit
import RxSwift

class OtherObservableViewController: BaseViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

//        delay()
//        delaySubscription()
//        materialize()
//        dematerialize()
        using()
    }

}

extension OtherObservableViewController {
    /// delay
    /// 将 Observable 的所有元素都先拖延一段设定好的时间，然后才将它们发送出来
    private func delay() {
        Observable.of(1, 2, 1)
            .delay(RxTimeInterval.seconds(3), scheduler: MainScheduler.instance)
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)
    }
    
    /// delaySubscription
    /// 可以进行延时订阅。即经过所设定的时间后，才对 Observable 进行订阅操作
    private func delaySubscription() {
        Observable.of(1, 2, 1)
            .delaySubscription(RxTimeInterval.seconds(3), scheduler: MainScheduler.instance)
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)
    }
    
    /// materialize
    /// 可以将序列产生的事件，转换成元素
    /// 通常一个有限的 Observable 将产生零个或者多个 onNext 事件，最后产生一个 onCompleted 或者onError事件
    /// 而 materialize 操作符会将 Observable 产生的这些事件全部转换成元素，然后发送出来
    private func materialize() {
        Observable.of(1, 2, 1)
            .materialize()
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)
        /**
         打印：
         next(1)
         next(2)
         next(1)
         completed
         */
    }
    
    /// dematerialize
    /// 和 materialize 正好相反，它可以将 materialize 转换后的元素还原
    private func dematerialize() {
        Observable.of(1, 2, 1)
            .materialize()
            .dematerialize()
            .subscribe(onNext: { print($0) })
            .disposed(by: disposeBag)
    }
    
    /// using
    /// 创建 Observable 时，同时会创建一个可被清除的资源，一旦 Observable 终止了，那么这个资源就会被清除掉了
    private func using() {
        // 一个无限序列（每隔0.1秒创建一个序列数）
        let infinteInterval$ = Observable<Int>
            .interval(RxTimeInterval.milliseconds(100), scheduler: MainScheduler.instance)
            .do {
                print("infinte$: \($0)")
            } onSubscribe: {
                print("开始订阅 infinite$")
            } onDispose: {
                print("销毁 infinite$")
            }
        
        // 一个有限序列（每隔0.5秒创建一个序列数，共创建3个）
        let limited$ = Observable<Int>
                .interval(RxTimeInterval.milliseconds(500), scheduler: MainScheduler.instance)
                .take(2)
                .do {
                    print("limited$: \($0)")
                } onSubscribe: {
                    print("开始订阅 limited$")
                } onDispose: {
                    print("销毁 limited$")
                }
        
        // 使用 using 操作符创建序列
        let o: Observable<Int> = Observable.using {
            return AnyDisposable(infinteInterval$.subscribe())
        } observableFactory: { _ in
            return limited$
        }
        _ = o.subscribe()
        
        /**
         开始订阅 infinite$
         开始订阅 limited$
         infinte$: 0
         infinte$: 1
         infinte$: 2
         infinte$: 3
         infinte$: 4
         limited$: 0
         infinte$: 5
         infinte$: 6
         infinte$: 7
         infinte$: 8
         infinte$: 9
         limited$: 1
         销毁 limited$
         销毁 infinite$
         */
    }
}

class AnyDisposable: Disposable {
    let _dispose: () -> ()
    
    init(_ disposable: Disposable) {
        _dispose = disposable.dispose
    }
    
    func dispose() {
        _dispose()
    }
}
